package com.hiray.demos.visualEffect

import androidx.recyclerview.widget.RecyclerView
import android.util.Log
import android.view.MotionEvent
import android.view.ViewConfiguration

class ScrollMultiSelectItemTouchListener(private var onItemTouchListener: OnItemSelectListener) : androidx.recyclerview.widget.RecyclerView.OnItemTouchListener {

    private val TAG = "ScrollMultiSelectItem"
    private var requestDisallowIntercept = false
    private var longPressCheck = LongPressCheck()
    private var isLongPressed = false
    private var currVisitPosition = -1
    private var mInitialY = -1
    var moved: Boolean = false

    override fun onTouchEvent(rv: androidx.recyclerview.widget.RecyclerView, e: MotionEvent) {
        when (e.action) {

            MotionEvent.ACTION_MOVE -> {
                val view = rv.findChildViewUnder(e.x, e.y)
                val childAdapterPosition = rv.getChildAdapterPosition(view!!)
                if (childAdapterPosition != currVisitPosition) {
                    currVisitPosition = childAdapterPosition
                    ensureVisible(rv, currVisitPosition, e.y - mInitialY)
                    onItemTouchListener.onItemVisited(currVisitPosition)
                }
            }
        }
    }

    override fun onInterceptTouchEvent(rv: androidx.recyclerview.widget.RecyclerView, e: MotionEvent): Boolean {
        var intercept = false
        when (e.action and MotionEvent.ACTION_MASK) {
            MotionEvent.ACTION_DOWN -> {
                Log.i(TAG, "onInterceptTouchEvent: DOWN")
                mInitialY = e.y.toInt()
                checkForLongPress(rv)
                return !requestDisallowIntercept and intercept
            }

            MotionEvent.ACTION_MOVE -> {
                Log.i(TAG, "onInterceptTouchEvent: moved ${e.x}  ${e.y}")
                moved = true
                intercept = isLongPressed
                return !requestDisallowIntercept and intercept
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                Log.i(TAG, "onInterceptTouchEvent: UP")
                isLongPressed = false
                intercept = false
                currVisitPosition =-1
                moved = false
                return !requestDisallowIntercept and intercept

            }

        }
        return !requestDisallowIntercept and intercept
    }

    /**
     * @param x
     * @param y
     */
    private fun ensureVisible(recyclerView: androidx.recyclerview.widget.RecyclerView, position: Int, fl: Float) {
        if (fl < 0) {
//            val firstView = recyclerView.getChildAt(0)
//            val pos = recyclerView.getChildViewHolder(firstView).adapterPosition
//            if (position == pos) recyclerView.scrollToPosition(position - 1)
            if (position - 1 >= 0) {
                recyclerView.scrollToPosition(position - 1)
            }
        } else {
//            val firstView = recyclerView.getChildAt(0)
//            val pos = recyclerView.getChildViewHolder(firstView).adapterPosition
//            if (position == pos) recyclerView.scrollToPosition(position - 1)
            if (position + 1 < recyclerView.adapter!!.itemCount)
                recyclerView.scrollToPosition(position + 1)
        }

    }

    private fun checkForLongPress(rv: androidx.recyclerview.widget.RecyclerView) {
        rv.postDelayed(longPressCheck, ViewConfiguration.getLongPressTimeout().toLong())
    }

    override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
        requestDisallowIntercept = disallowIntercept
    }

    inner class LongPressCheck : Runnable {
        override fun run() {
            Log.i(TAG, "run: longPressCheck")
            if (moved.not()) {
                Log.i(TAG, "LongPressed trigger!")
                isLongPressed = true
                onItemTouchListener.onPrePare()
            }
        }

    }

    interface OnItemSelectListener {

        /**
         * when user long press item ,then notify we are ready to select
         * item ,you can do some prepare work(e.g. change the item's background ,which give user a hint we
         * are ready to select)
         */
        fun onPrePare()

        /**
         * when certain item is visited(finger is now touch the item);
         * no matter the item is selected or not ,user is responsible for the current
         * item state
         * @param position the item's adapter position
         */
        fun onItemVisited(position: Int)


    }
}